﻿'imports in ordine alfabetico
Imports System.Diagnostics
Imports System.Globalization
Imports System.IO
Imports System.Management
Imports System.Runtime.InteropServices
Imports System.Text

Public Class FRM_TempAndStress

#Region "PInvoke alle API unmanaged"

    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function FindWindowEx(ByVal parentHandle As IntPtr, ByVal childAfter As IntPtr, ByVal lclassName As String, ByVal windowTitle As String) As IntPtr
    End Function
    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
    End Function
    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
    End Function

#End Region

#Region "Variabili globali"

    'Linpack
    Dim LeggiOutput As Boolean
    Dim LinpackDovrebbeEssereInEsecuzione As Boolean
    Dim MigliorTempo, MigliorGFlops As Double
    Dim SommaTempo, SommaGFlops As Double
    Dim LDA As Integer
    Dim NumeroElementi As Integer
    Dim DimensioneProblema As Long
    Dim LinProcess As Process
    Dim LinInputFileName As String

    'OpenHardwareMonitor
    Dim OHM_Utilizzo(0) As Double
    Dim OHM_Temperatura(0) As Double
    Dim OHM_UtilizzoMassimo(0) As Double
    Dim OHM_TemperaturaMassima(0) As Double
    Dim OHM_VCore As Double
    Dim OHM_NumeroCPU As Integer
    Dim OHM_NumeroCore As Integer
    Dim OHM_NomeCPU As String
    Dim OHM_Frequenza As Double
    Dim OHM_FSB As Double
    Dim OHM_Moltiplicatore As Double
    Dim ClasseOHMInfo As New OHM_Info

    'Temp and Stress
    Dim ListaImmagini As New ImageList
    Dim NomeCPU As String
    Public Shared STR() As String
    Dim LetturaSensori As Threading.Thread
    Dim LetturaSensoriTimer As New Timers.Timer

    'API unmanaged
    Private Const WM_CLOSE As Integer = &H10

#End Region

#Region "Funzioni generiche"

    Sub Avvio()
        'elimino eventuali file all'interno della cartella Linpack\Input
        Svuota_Cartella("Linpack\Input")

        'avvio il thread per la lettura dei sensori da OpenHardwareMonitorLib.dll
        LetturaSensori = New Threading.Thread(AddressOf Leggi_sensori_OHM)
        LetturaSensori.Start()

        Try
            'preparo il TreeListView delle temperature
            Populate_TLV_Temp()
            'aggiornamento delle info manuale
            Update_Info()
            'forzo il resize di LST_Stress per assegnare la giusta larghezza alle colonne
            LST_Stress_Resize(Nothing, Nothing)
        Catch ex As Exception
            MsgBox(STR(14) & vbCrLf & STR(2) & ex.ToString, MsgBoxStyle.Critical, STR(3))
            Me.Close()
            Exit Sub
        End Try

        Try
            'carico le icone per TLV_Temp
            CaricaIconeTreeListView()
        Catch
        End Try
    End Sub

    'Termina un processo per nome
    Public Shared Sub Killa_Processo(ByVal NomeProcesso As String)
        Dim processi() As Process = Process.GetProcesses
        For i = 0 To processi.GetUpperBound(0)
            If processi(i).ProcessName = NomeProcesso Then
                processi(i).Kill()
            End If
        Next
    End Sub

    Sub Svuota_Cartella(ByVal Percorso As String)
        For Each file As String In My.Computer.FileSystem.GetFiles(Percorso)
            My.Computer.FileSystem.DeleteFile(file, FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.DeletePermanently)
        Next
    End Sub

    Function Stringa_Casuale(ByVal lunghezza As Integer) As String
        Dim caratteri As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
        Dim ch As Char
        Dim casuale As New Random
        Dim builder As New StringBuilder
        For i = 1 To lunghezza
            ch = caratteri(casuale.Next(0, caratteri.Length))
            builder.Append(ch)
        Next
        Return builder.ToString
    End Function

    Function Architettura_CPU() As String
        If Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Hardware\Description\System\CentralProcessor\0").GetValue("Identifier").ToString.Contains("x86") Then
            Return "32"
        Else
            Return "64"
        End If
    End Function

    'Restituisce l'ID del processo a cui è associato un determinato Handle
    Function Handle_a_ID(ByVal HandleFinestra As Long) As Long
        Dim ID As Long
        GetWindowThreadProcessId(HandleFinestra, ID)
        Return ID
    End Function

    'Trova un processo per nome e ID e lo termina
    Public Sub Trova_e_Termina(ByVal titolo As String, ByVal id As Integer)
        Dim Handle As IntPtr
        Dim Parent As Long = 0 'sarebbe il desktop
        Dim UltimaFinestra As Long = 0
        Do
            Handle = FindWindowEx(Parent, UltimaFinestra, vbNullString, titolo)
            If Handle_a_ID(Handle) = id Then Exit Do 'solo se l'ho avviato io
            UltimaFinestra = Handle
        Loop Until Handle = 0
        SendMessage(Handle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero)
    End Sub

#End Region

#Region "Interfaccia grafica"

    'Gestisco la chiusura
    Private Sub TempAndStress_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        'mi nascondo
        Me.Hide()
        FRM_Info.Hide()
        FRM_PI.Hide()

        'fermo il timer prima di chiudere
        LetturaSensoriTimer.Stop()
        LetturaSensoriTimer.Dispose()

        Try 'se alla chiusura del programma, Linpack è ancora in esecuzione, lo distruggo
            LinProcess.Kill()
        Catch
        End Try
    End Sub

    'Preparo il caricamento
    Private Sub TempAndStress_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Try
            'imposto la lingua
            If CultureInfo.CurrentCulture.ThreeLetterISOLanguageName() = "ita" Then
                Cambia_Lingua("Italiano")
            Else
                Cambia_Lingua("English")
            End If

            'chiamo la routine di avvio
            Avvio()
        Catch ex As Exception
            MsgBox(STR(1) & vbCrLf & STR(2) & ex.ToString, MsgBoxStyle.Critical, STR(3))
            Me.Close()
            Exit Sub
        End Try
    End Sub

    'Assegno le giuste icone in TLV_Temp
    Sub CaricaIconeTreeListView()
        Dim IconCPU As Drawing.Image = My.Resources.ICO_CPU
        ListaImmagini.Images.Add(IconCPU)
        Dim IconTermometroCaldo As Drawing.Image = My.Resources.ICO_TermometroCaldo
        ListaImmagini.Images.Add(IconTermometroCaldo)
        Dim IconUtilizzo As Drawing.Image = My.Resources.ICO_Utilizzo
        ListaImmagini.Images.Add(IconUtilizzo)
        TLV_Temp.Images = ListaImmagini
    End Sub

    'Preparo TLV_Temp (aggiungo il giusto numero di nodi in base al numero di CPU e Core)
    Sub Populate_TLV_Temp()
        TLV_Temp.Nodes.Clear()
        If Not OHM_NumeroCPU = 0 Then
            TLV_Temp.ViewOptions.ShowPlusMinus = True
            Dim i, g As Integer
            For i = 1 To OHM_NumeroCPU
                TLV_Temp.Nodes.Add("CPU " & i - 1)
                TLV_Temp.Nodes(i - 1).ImageId = 0
                TLV_Temp.Nodes(i - 1).Nodes.Add(STR(88))
                TLV_Temp.Nodes(i - 1).Nodes(0).ImageId = 1
                TLV_Temp.Nodes(i - 1).Nodes.Add(STR(19))
                TLV_Temp.Nodes(i - 1).Nodes(1).ImageId = 2
                For g = 1 To OHM_NumeroCore
                    TLV_Temp.Nodes(i - 1).Nodes(0).Nodes.Add("Core " & g - 1)
                    TLV_Temp.Nodes(i - 1).Nodes(1).Nodes.Add("Core " & g - 1)
                Next
                TLV_Temp.Nodes(i - 1).ExpandAll()
            Next
        Else
            TLV_Temp.Nodes.Add(STR(15))
            TLV_Temp.Nodes(0).Nodes.Add("")
            TLV_Temp.ViewOptions.ShowPlusMinus = False
        End If
    End Sub

    'Aggiorno le informazioni in TLV_Temp
    Sub Update_TLV_temp()
        If Not OHM_NumeroCPU = 0 Then
            For i = 1 To OHM_NumeroCPU
                For g = 1 To OHM_NumeroCore
                    TLV_Temp.Nodes(i - 1).Nodes(0).Nodes(g - 1).Item(1) = Math.Round(OHM_Temperatura(i * g), 0) & "°C"
                    TLV_Temp.Nodes(i - 1).Nodes(0).Nodes(g - 1).Item(2) = Math.Round(OHM_TemperaturaMassima(i * g), 0) & "°C"
                    TLV_Temp.Nodes(i - 1).Nodes(1).Nodes(g - 1).Item(1) = Math.Round(OHM_Utilizzo(i * g), 0).ToString & "%"
                    TLV_Temp.Nodes(i - 1).Nodes(1).Nodes(g - 1).Item(2) = Math.Round(OHM_UtilizzoMassimo(i * g), 0) & "%"
                Next
            Next
            TXT_CPUVCore.Text = Math.Round(OHM_VCore, 3) & "v"
            TLV_Temp.Invalidate()
        Else
            TXT_CPUVCore.Text = STR(15)
            Populate_TLV_Temp()
        End If
    End Sub

    Private Sub LST_Stress_ColumnWidthChanging(sender As System.Object, e As System.Windows.Forms.ColumnWidthChangingEventArgs) Handles LST_Stress.ColumnWidthChanging
        e.Cancel = True
        e.NewWidth = LST_Stress.Columns(e.ColumnIndex).Width()
    End Sub

    Private Sub LST_Stress_Resize(sender As System.Object, e As System.EventArgs) Handles LST_Stress.Resize
        LST_Stress.Columns(1).Width = LST_Stress.Width / 4
        LST_Stress.Columns(2).Width = LST_Stress.Width / 4
        LST_Stress.Columns(3).Width = LST_Stress.Width / 4
        LST_Stress.Columns(4).Width = LST_Stress.Width / 4
    End Sub

#End Region

#Region "Lettura sensori"

    'Procedura di aggiornamento dei valori letti da OpenHardwareMonitor
    Delegate Sub Update_Info_Delegate()
    Sub Update_Info()
        'se è cambiato il nome della CPU, ridisegno TLV_Temp
        If Not OHM_NomeCPU = NomeCPU Then
            NomeCPU = OHM_NomeCPU
            Populate_TLV_Temp()
        End If

        'se la CPU è riconosciuta, aggiorno l'interfaccia grafica con i nuovi valori
        If Not OHM_NumeroCore = 0 Then
            Update_TLV_temp()
            TXT_CPUName.Text = OHM_NomeCPU
            TXT_CPUSpeed.Text = Format(Math.Round(OHM_Frequenza / 1000, 2), "0.00") & "GHz (" & Math.Round(OHM_FSB, 2) & "MHz x " & OHM_Moltiplicatore & ")"
            TXT_PhysicalCPU.Text = OHM_NumeroCPU
            TXT_CorePerCPU.Text = OHM_NumeroCore
        Else
            Populate_TLV_Temp()
        End If

        'controllo se linpack è stato chiuso in modo anomalo
        If Not LinProcess Is Nothing Then
            If LinpackDovrebbeEssereInEsecuzione And LinProcess.HasExited Then
                LeggiOutput = False
                LinpackDovrebbeEssereInEsecuzione = False
                Invoke(New Imposta_Testo_BTN_StartStop_Delegate(AddressOf Imposta_Testo_BTN_StartStop), STR(20))
                MsgBox(STR(16) & vbCrLf & STR(17), MsgBoxStyle.Exclamation, STR(18))
            End If
        End If
    End Sub

    'Preparo la lettura dei sensori da OpenHardwareMonitor
    Sub Leggi_sensori_OHM()
        AddHandler LetturaSensoriTimer.Elapsed, AddressOf Leggi_sensori_OHM_TMR
        LetturaSensoriTimer.Interval = 1000
        LetturaSensoriTimer.Start()
    End Sub

    'Timer che aggiorna le informazioni di OpenHardwareMonitor
    Sub Leggi_sensori_OHM_TMR()
        ClasseOHMInfo.UpdateInfo()
        OHM_Temperatura = ClasseOHMInfo.Temperatura
        OHM_TemperaturaMassima = ClasseOHMInfo.TemperaturaMassima
        OHM_Utilizzo = ClasseOHMInfo.Utilizzo
        OHM_UtilizzoMassimo = ClasseOHMInfo.UtilizzoMassimo
        OHM_NomeCPU = ClasseOHMInfo.NomeCPU
        OHM_NumeroCPU = ClasseOHMInfo.NumeroCPU
        OHM_NumeroCore = ClasseOHMInfo.NumeroCore
        OHM_VCore = ClasseOHMInfo.VCore
        OHM_Frequenza = ClasseOHMInfo.Frequenza
        OHM_FSB = ClasseOHMInfo.FSB
        OHM_Moltiplicatore = ClasseOHMInfo.Moltiplicatore
        BeginInvoke(New Update_Info_Delegate(AddressOf Update_Info))
    End Sub

#End Region

#Region "Stress Test"

    'Gestisco la pressione del pulsante Stressa/Ferma
    Private Sub BTN_StartStop_Click(sender As System.Object, e As System.EventArgs) Handles BTN_StartStop.Click
        If BTN_StartStop.Text = STR(20) Then
            'controllo che l'utente abbia scritto dati idonei nella casella della RAM e dei cicli
            If Not IsNumeric(TXT_RAM.Text) Then
                MsgBox(STR(21), MsgBoxStyle.Critical, STR(18))
                Exit Sub
            End If

            If Val(TXT_RAM.Text) < 10 Or Val(TXT_RAM.Text) > 32768 Then
                MsgBox(STR(22), MsgBoxStyle.Critical, STR(18))
                Exit Sub
            End If

            If Not IsNumeric(TXT_Loop.Text) Then
                MsgBox(STR(23), MsgBoxStyle.Critical, STR(18))
                Exit Sub
            End If

            If Val(TXT_Loop.Text) < 1 Or Val(TXT_Loop.Text) > 256 Then
                MsgBox(STR(24), MsgBoxStyle.Critical, STR(18))
                Exit Sub
            End If

            'elimino eventuali file all'interno della cartella Linpack\Input
            Svuota_Cartella("Linpack\Input")

            'creo il nome del file di input per linpack
            LinInputFileName = "lininput_" & Stringa_Casuale(8)

            'creo il file e ci scrivo dentro
            DimensioneProblema = Math.Floor((Math.Sqrt(2097152 * (TXT_RAM.Text + 1) - 4160079) - 195) / 4) 'Thank you very very much Alexander Gusev, you are my hero <3
            'promemoria: formula per ricavare la memoria dalla dimensione del problema: mem = (size + 95) * (size + 2.5) / 131072 + 2
            LDA = Calcola_LDA(DimensioneProblema)
            Dim FileStream As FileStream = File.Create("Linpack\Input\" & LinInputFileName)
            FileStream.Close()
            Dim StreamWriter As StreamWriter = New StreamWriter("Linpack\Input\" & LinInputFileName)
            StreamWriter.WriteLine(STR(25))
            StreamWriter.WriteLine(STR(26))
            StreamWriter.WriteLine("1")
            StreamWriter.WriteLine(DimensioneProblema.ToString)
            StreamWriter.WriteLine(LDA.ToString)
            StreamWriter.WriteLine(TXT_Loop.Text)
            StreamWriter.WriteLine("4")
            StreamWriter.Close()

            'avvio il processo di linpack
            LinProcess = New Process
            If Architettura_CPU() = "32" Then LinProcess.StartInfo.FileName = "Linpack\32 bit\linpack.exe" Else LinProcess.StartInfo.FileName = "Linpack\64 bit\linpack.exe"
            LinProcess.StartInfo.Arguments = """Linpack\Input\" & LinInputFileName & """"
            LinProcess.StartInfo.CreateNoWindow = True
            LinProcess.StartInfo.UseShellExecute = False
            LinProcess.StartInfo.RedirectStandardOutput = True
            AddHandler LinProcess.OutputDataReceived, AddressOf Output_LinProcess
            Invoke(New Imposta_Testo_BTN_StartStop_Delegate(AddressOf Imposta_Testo_BTN_StartStop), STR(27))
            Invoke(New Pulisci_LST_Stress_Delegate(AddressOf Pulisci_LST_Stress))
            SommaTempo = 0
            SommaGFlops = 0
            NumeroElementi = 0
            MigliorTempo = Double.MaxValue
            MigliorGFlops = 0
            LinProcess.Start()
            LinProcess.BeginOutputReadLine()

            'setto la variabile globale
            LinpackDovrebbeEssereInEsecuzione = True
        Else
            LinProcess.Kill() 'termino linpack
            'setto la variabile globale
            LinpackDovrebbeEssereInEsecuzione = False
            Invoke(New Imposta_Testo_BTN_StartStop_Delegate(AddressOf Imposta_Testo_BTN_StartStop), STR(20))
        End If
    End Sub

    'Gestisco l'output del processo di linpack
    Sub Output_LinProcess(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
        Try
            Dim out As String = e.Data

            'inizio a leggere se...
            If out = "Size   LDA    Align. Time(s)    GFlops   Residual     Residual(norm)" Then
                LeggiOutput = True
            End If

            If LeggiOutput Then
                If out.StartsWith(DimensioneProblema.ToString) Then
                    Dim valore(4) As String
                    Dim Temp As String
                    valore(0) = "" 'la prima colonna è vuota e invisibile, altrimenti sono costretto a mettere il text align a sinistra, il che mi scazza
                    valore(1) = DimensioneProblema.ToString
                    Temp = out.Substring(out.IndexOf(" ")).TrimStart(" ") 'via la dimensione
                    valore(2) = LDA.ToString
                    Temp = Temp.Substring(Temp.IndexOf(" ")).TrimStart(" ") ' via l'LDA
                    Temp = Temp.Substring(Temp.IndexOf(" ")).TrimStart(" ") ' via l'Align
                    valore(3) = Temp.Substring(0, Temp.IndexOf(" "))
                    Temp = Temp.Substring(Temp.IndexOf(" ")).TrimStart(" ") ' via il tempo
                    valore(4) = Temp.Substring(0, Temp.IndexOf(" "))
                    SommaTempo += Val(valore(3))
                    SommaGFlops += Val(valore(4))
                    NumeroElementi += 1
                    If Val(valore(3)) < MigliorTempo Then MigliorTempo = Val(valore(3))
                    If Val(valore(4)) > MigliorGFlops Then MigliorGFlops = Val(valore(4))
                    Dim RigaListView As New ListViewItem(valore)
                    BeginInvoke(New Aggiungi_Riga_LST_Stress_Delegate(AddressOf Aggiungi_Riga_LST_Stress), RigaListView)
                End If
            End If

            'smetto di leggere se...
            If out = "Performance Summary (GFlops)" Then
                LinpackDovrebbeEssereInEsecuzione = False
                LeggiOutput = False
                Invoke(New Imposta_Testo_BTN_StartStop_Delegate(AddressOf Imposta_Testo_BTN_StartStop), STR(20))

                'aggiungo alla lista i valori medi e quelli migliori
                Dim ArrayVuoto(4) As String
                Dim RigaVuota As New ListViewItem(ArrayVuoto)
                BeginInvoke(New Aggiungi_Riga_LST_Stress_Delegate(AddressOf Aggiungi_Riga_LST_Stress), RigaVuota)

                Dim ArrayMedia(4) As String
                ArrayMedia(1) = STR(28)
                Dim RigaMedia As New ListViewItem(ArrayMedia)
                BeginInvoke(New Aggiungi_Riga_LST_Stress_Delegate(AddressOf Aggiungi_Riga_LST_Stress), RigaMedia)

                Dim ArrayValori(4) As String
                ArrayValori(1) = DimensioneProblema
                ArrayValori(2) = LDA
                ArrayValori(3) = Format(Math.Round(SommaTempo / NumeroElementi, 3), "0.000")
                ArrayValori(4) = Format(Math.Round(SommaGFlops / NumeroElementi, 4), "0.0000")
                Dim RigaValori As New ListViewItem(ArrayValori)
                BeginInvoke(New Aggiungi_Riga_LST_Stress_Delegate(AddressOf Aggiungi_Riga_LST_Stress), RigaValori)

                RigaVuota = New ListViewItem(ArrayVuoto)
                BeginInvoke(New Aggiungi_Riga_LST_Stress_Delegate(AddressOf Aggiungi_Riga_LST_Stress), RigaVuota)

                Dim ArrayMigliore(4) As String
                ArrayMigliore(1) = STR(29)
                Dim RigaMigliore As New ListViewItem(ArrayMigliore)
                BeginInvoke(New Aggiungi_Riga_LST_Stress_Delegate(AddressOf Aggiungi_Riga_LST_Stress), RigaMigliore)

                Dim ArrayValoriMigliori(4) As String
                ArrayValoriMigliori(1) = DimensioneProblema
                ArrayValoriMigliori(2) = LDA
                ArrayValoriMigliori(3) = Format(Math.Round(MigliorTempo, 3), "0.000")
                ArrayValoriMigliori(4) = Format(Math.Round(MigliorGFlops, 4), "0.0000")
                Dim RigaValoriMigliori As New ListViewItem(ArrayValoriMigliori)
                BeginInvoke(New Aggiungi_Riga_LST_Stress_Delegate(AddressOf Aggiungi_Riga_LST_Stress), RigaValoriMigliori)
            End If
        Catch
        End Try
    End Sub

    'Calcolo l'LDA in base alla dimensione del problema
    Function Calcola_LDA(ByVal DimensioneProblema As Integer) As Integer
        Dim LDA As Integer = Math.Ceiling(DimensioneProblema / 8)
        If LDA Mod 2 Then Return LDA * 8 Else Return (LDA + 1) * 8
    End Function

    Delegate Sub Pulisci_LST_Stress_Delegate()
    Sub Pulisci_LST_Stress()
        LST_Stress.Items.Clear()
    End Sub

    Delegate Sub Imposta_Testo_BTN_StartStop_Delegate(ByVal testo As String)
    Sub Imposta_Testo_BTN_StartStop(ByVal testo As String)
        BTN_StartStop.Text = testo
    End Sub

    Delegate Sub Aggiungi_Riga_LST_Stress_Delegate(ByVal riga As ListViewItem)
    Sub Aggiungi_Riga_LST_Stress(ByVal riga As ListViewItem)
        LST_Stress.Items.Add(riga)
    End Sub

    Private Sub TXT_RAM_o_LOOP_Premuto_Invio(sender As System.Object, e As System.Windows.Forms.KeyPressEventArgs) Handles TXT_RAM.KeyPress, TXT_Loop.KeyPress
        If e.KeyChar = Convert.ToChar(Keys.Enter) Then
            e.Handled = True
            BTN_StartStop.PerformClick()
        End If
    End Sub

#End Region

#Region "Menu"

    Private Sub MEN_Screenshot_Click(sender As System.Object, e As System.EventArgs) Handles MEN_File_SalvaScreenshot.Click
        Dim frm As Form = Form.ActiveForm
        Dim bmp As New Bitmap(frm.Width, frm.Height)
        frm.DrawToBitmap(bmp, New Rectangle(0, 0, bmp.Width, bmp.Height))
        If SAV_Dialogo.ShowDialog = Windows.Forms.DialogResult.OK Then
            Try
                bmp.Save(SAV_Dialogo.FileName, Imaging.ImageFormat.Png)
            Catch
                MsgBox(STR(30), MsgBoxStyle.Exclamation, STR(18))
            End Try
        End If
    End Sub

    Private Sub MEN_Esci_Click(sender As System.Object, e As System.EventArgs) Handles MEN_File_Esci.Click
        Me.Close()
    End Sub

    Private Sub MEN_Info_Click(sender As System.Object, e As System.EventArgs) Handles MEN_Info.Click
        FRM_Info.ShowDialog()
        FRM_Info.BringToFront()
    End Sub

    Private Sub MEN_Benchmark_PIGreco_Click(sender As System.Object, e As System.EventArgs) Handles MEN_Benchmark_PIGreco.Click
        FRM_PI.ShowDialog()
    End Sub

    Private Sub MEN_Licenze_TempAndStress_Click(sender As System.Object, e As System.EventArgs) Handles MEN_Licenze_TempAndStress.Click
        Try
            Process.Start(Application.StartupPath & "\Licenses\Temp and Stress.License.txt")
        Catch
            MsgBox(STR(31) & vbCrLf & STR(32), MsgBoxStyle.Exclamation, STR(3))
        End Try
    End Sub

    Private Sub MEN_Licenze_Linpack_Click(sender As System.Object, e As System.EventArgs) Handles MEN_Licenze_Linpack.Click
        Try
            Process.Start(Application.StartupPath & "\Licenses\Linpack.EULA.rtf")
        Catch
            MsgBox(STR(31) & vbCrLf & STR(32), MsgBoxStyle.Exclamation, STR(3))
        End Try
    End Sub

    Private Sub MEN_Licenze_OpenHardwareMonitor_Click(sender As System.Object, e As System.EventArgs) Handles MEN_Licenze_OpenHardwareMonitor.Click
        Try
            Process.Start(Application.StartupPath & "\Licenses\OpenHardwareMonitor.License.html")
        Catch
            MsgBox(STR(31) & vbCrLf & STR(32), MsgBoxStyle.Exclamation, STR(3))
        End Try
    End Sub

    Private Sub MEN_Licenze_TreeViewColumns_Click(sender As System.Object, e As System.EventArgs) Handles MEN_Licenze_TreeViewColumns.Click
        Try
            Process.Start(Application.StartupPath & "\Licenses\TreeViewWithColumns.License.htm")
        Catch
            MsgBox(STR(31) & vbCrLf & STR(32), MsgBoxStyle.Exclamation, STR(3))
        End Try
    End Sub


    Private Sub MEN_Licenze_ycruncher_Click(sender As System.Object, e As System.EventArgs) Handles MEN_Licenze_ycruncher.Click
        Try
            Process.Start(Application.StartupPath & "\Licenses\ycruncher.Readme.txt")
        Catch
            MsgBox(STR(31) & vbCrLf & STR(32), MsgBoxStyle.Exclamation, STR(3))
        End Try
    End Sub

    Private Sub MEN_FlagENG_Click(sender As System.Object, e As System.EventArgs) Handles MEN_FlagENG.Click
        Cambia_Lingua("English")
    End Sub

    Private Sub MEN_FlagITA_Click(sender As System.Object, e As System.EventArgs) Handles MEN_FlagITA.Click
        Cambia_Lingua("Italiano")
    End Sub

#End Region

#Region "Linguaggio"

    'Cambio la lingua dei nodi all'interno di TLV_Temp
    Sub Aggiorna_Lingua_TLV_Temp()
        Try
            If Not OHM_NumeroCPU = 0 Then
                Dim i As Integer
                For i = 0 To OHM_NumeroCPU - 1
                    TLV_Temp.Nodes(i).Nodes(0).Item(0) = STR(88)
                    TLV_Temp.Nodes(i).Nodes(1).Item(0) = STR(19)
                Next
            Else
                TLV_Temp.Nodes.Add(STR(15))
                TLV_Temp.Nodes(0).Nodes.Add("")
                TLV_Temp.ViewOptions.ShowPlusMinus = False
            End If
        Catch
        End Try
    End Sub

    Public Sub Cambia_Lingua(ByVal Lingua As String)
        Dim Righe() As String
        Dim Riga As String
        Dim Indice As Integer
        Dim Traduzione As String

        Select Case Lingua
            Case "Italiano"
                Righe = My.Resources.Italiano.Split(vbCrLf)
            Case Else
                Righe = My.Resources.English.Split(vbCrLf)
        End Select

        ReDim STR(Righe.Length)

        For Each Riga In Righe
            Indice = Riga.Substring(2, 3)
            Traduzione = Riga.Substring(6)
            STR(Indice) = Traduzione
        Next

        Aggiorna_Traduzione_GUI()
    End Sub

    Sub Aggiorna_Traduzione_GUI()
        'Titoli form
        FRM_PI.Text = STR(34)
        FRM_Info.Text = STR(35)

        'Form principale
        If BTN_StartStop.Enabled Then BTN_StartStop.Text = STR(20) Else BTN_StartStop.Text = STR(27)
        MEN_Info.Text = STR(35)
        MEN_File.Text = STR(36)
        MEN_Licenze.Text = STR(37)
        MEN_Benchmark.Text = STR(38)
        MEN_File_SalvaScreenshot.Text = STR(39)
        MEN_File_Esci.Text = STR(40)
        MEN_Benchmark_PIGreco.Text = STR(41)
        LBL_CPUName.Text = STR(42)
        LBL_CPUSpeed.Text = STR(43)
        LBL_VCore.Text = STR(45)
        LBL_PhysicalCPU.Text = STR(46)
        LBL_CorePerCPU.Text = STR(47)
        BOX_Temp.Text = STR(48)
        LBL_Stress.Text = STR(49)
        LBL_RAM.Text = STR(50)
        LBL_Loop.Text = STR(51)
        LBL_MB.Text = STR(52)
        BOX_Risultati.Text = STR(53)
        LST_Stress.Columns(1).Text = STR(54)
        LST_Stress.Columns(2).Text = STR(55)
        LST_Stress.Columns(3).Text = STR(56)
        LST_Stress.Columns(4).Text = STR(57)
        TLV_Temp.Columns(0).Caption = STR(87)
        TLV_Temp.Columns(1).Caption = STR(90)
        TLV_Temp.Columns(2).Caption = STR(91)
        Aggiorna_Lingua_TLV_Temp()

        'Form PI
        FRM_PI.LBL_Decimali.Text = STR(61)
        FRM_PI.LBL_Thread.Text = STR(62)
        FRM_PI.CMB_Decimali.Items(0) = STR(63)
        FRM_PI.CMB_Decimali.Items(1) = STR(64)
        FRM_PI.CMB_Decimali.Items(2) = STR(65)
        FRM_PI.CMB_Decimali.Items(3) = STR(66)
        FRM_PI.CMB_Decimali.Items(4) = STR(67)
        FRM_PI.CMB_Decimali.Items(5) = STR(68)
        FRM_PI.CMB_Thread.Items(0) = STR(69)
        FRM_PI.CMB_Thread.Items(1) = STR(70)
        FRM_PI.BTN_Bench.Text = STR(71)

        'Form Info
        FRM_Info.LBL_Autore.Text = STR(72) & "Nicola Lagnena, a.k.a. nic1294"
        FRM_Info.LBL_EMail.Text = STR(73)
        FRM_Info.LBL_Linpack.Text = STR(74) & "Intel® Math Kernel Library 10.2 - Linpack" & Environment.NewLine & "Copyright © Intel® Corporation"
        FRM_Info.LBL_Linpack.LinkArea = New LinkArea(1, 0)
        FRM_Info.LBL_Linpack.LinkArea = New LinkArea(FRM_Info.LBL_Linpack.Text.IndexOf("Linpack"), 7)
        FRM_Info.LBL_OHM.Text = STR(74) & "Open Hardware Monitor 0.5.1 Beta" & vbCrLf & "Copyright © Michael Möller"
        FRM_Info.LBL_OHM.LinkArea = New LinkArea(1, 0)
        FRM_Info.LBL_OHM.LinkArea = New LinkArea(FRM_Info.LBL_OHM.Text.IndexOf("Open Hardware Monitor"), 21)
        FRM_Info.LBL_TreeListView.Text = STR(74) & "TreeView with Columns" & vbCrLf & "Copyright © Jesper Kristiansen"
        FRM_Info.LBL_TreeListView.LinkArea = New LinkArea(1, 0)
        FRM_Info.LBL_TreeListView.LinkArea = New LinkArea(FRM_Info.LBL_TreeListView.Text.IndexOf("TreeView with Columns"), 21)
        FRM_Info.LBL_ycruncher.Text = STR(74) & "y-cruncher 0.5.5 Build 9180 (fix 2)" & vbCrLf & "Copyright © Alexander J. Yee"
        FRM_Info.LBL_ycruncher.LinkArea = New LinkArea(1, 0)
        FRM_Info.LBL_ycruncher.LinkArea = New LinkArea(FRM_Info.LBL_ycruncher.Text.IndexOf("y-cruncher"), 10)
        FRM_Info.LBL_LinX.Text = STR(75) & vbCrLf & STR(76)
        FRM_Info.LBL_LinX.LinkArea = New LinkArea(1, 0)
        FRM_Info.LBL_LinX.LinkArea = New LinkArea(FRM_Info.LBL_LinX.Text.IndexOf("LinX"), 4)
        FRM_Info.LBL_Icone.Text = STR(89)
        FRM_Info.LBL_Icone.LinkArea = New LinkArea(1, 0)
        FRM_Info.LBL_Icone.LinkArea = New LinkArea(FRM_Info.LBL_Icone.Text.IndexOf("Yusuke Kamiyamane"), 17)
        FRM_Info.LBL_Tester.Text = STR(79) & vbCrLf & STR(80)
        FRM_Info.LBL_Attenzione.Text = STR(81) & vbCrLf & STR(82) & vbCrLf & STR(83) & vbCrLf & STR(84) & vbCrLf & STR(85)
    End Sub

#End Region

End Class

